// 在 type、interface 中可以使用逗号、分号，class 中不能用逗号。不过三者都支持行结尾不要符号。
interface car {
  color: string;
  readonly price: number,
  size?: number
}
let BWM: car = { color: 'blue', price: 100, size: 3 }
console.log(BWM); // {color: "blue", price: 100, size: 3}
let obj: object = { color: 'blue', price: 100, size: 3 }
console.log(BWM == obj); // false

// type 关键字是用来声明类型变量的

// 交叉类型 并集
type newType = number & string;
let a: newType;
interface A { d: number, z: string, }
interface B { f: string, g: string, }
type C = A & B
let b: C = { d: 123, z: '123', f: '456', g: '789'}

// 联合类型 交集
interface F { a: string, b: number }
interface D { c: number, b: string }
interface E { d: string, b: string }
let c: F | D | E = { b: '1', d: '2', a: '3' }
console.log(c); // {b: "1", d: "2", a: "3"}

// 函数中使用接口
function printCar(obj: car) {
  // obj.price = 123123 // 报错 只读属性readonly price只读
  console.log(obj.color, obj.price, obj.size);
}
printCar({ color: 'white', price: 2000000, size: 3 }) // 'white' 2000000 3
// 可选属性? size为可选
printCar({ color: 'white', price: 2000000 }) // 'white' 2000000 undefined

let myCar: Array<car> =[
  { color: 'black', price: 300000 },
  { color: 'yellow', price: 500000, size: 5 }
]
let yourCar: ReadonlyArray<car> = myCar
// yourCar[0] = { color: 'blue', price: 300000 } // 报错,只读
yourCar[0].color = 'gray'
console.log(yourCar[0].color);// 'gray'

myCar = yourCar as car[] // 类型断言  <car>yourCar
console.log(myCar[0].color); // 'gray'


// 额外的属性检查
interface SquareConfig {
  color?: string
  width?: number
}
function createSquare(config: SquareConfig) {
  console.log(config.color, config.width);
}
// let mySquare1 = createSquare({ colour: 'red', width: 100 }) // colour: 'red'报错，ts会进行额外属性检查，导致不认识colour
let mySquare2 = createSquare({ colour: 'red', width: 100 } as SquareConfig) // 1. 使用类型断言规避额外的属性检查
let squareOption: object = { colour: 'red', width: 100 } // 打印: undefined 100
let mySquare3 = createSquare(squareOption) // 使用对象赋值的方式绕过额外属性检查 // 打印: undefined 100